#include "mainwindow.h"

#include <QApplication>
#include <QsLog.h>
#include "Utils.h"

using namespace QsLogging;

void initLogger(const QString& logDir);
#if 1
int main(int argc, char *argv[])
{
    QCoreApplication::setOrganizationName("Chahu666");
    QCoreApplication::setOrganizationDomain("https://gitee.com/chahu666");
    QCoreApplication::setApplicationName("NetworkScanner");
    QCoreApplication::setApplicationVersion("1.0");

// 适配高分辨率
#if(QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
    QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
#elif(QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

    QApplication a(argc, argv);

    // 初始化日志库，必须在QApplication初始化之后，不然QApplication::applicationDirPath()没有值
    QString logDir = QApplication::applicationDirPath() + "/logs";
    initLogger(logDir);

    QString vInfo = QString("%1 V%2").arg(QCoreApplication::applicationName()).arg(QCoreApplication::applicationVersion());
    qDebug() << vInfo;
    QLOG_INFO() << vInfo;

    MainWindow w;
    w.show();

    return a.exec();
}

void initLogger(const QString& logDir)
{
    if(Utils::mkDirs(logDir))
    {
        Logger& logger = Logger::instance();
        logger.setLoggingLevel(QsLogging::TraceLevel);
        //    QString timeStr = QDate::currentDate().toString("yyyy-MM-dd");
        //    QDateTime time = QDateTime::fromString(timeStr,"yyyy-MM-dd");
        QString logFile = QString("%1/run.log").arg(logDir);
        DestinationPtr des(
            DestinationFactory::MakeFileDestination(logFile,
                                                    EnableLogRotation,
                                                    MaxSizeBytes(1*1024*1024),
                                                    MaxOldLogCount(1)));
        logger.addDestination(des);
        QLOG_INFO() << "initLogger() success logDir=" << logDir;
    }
    else
    {
        QLOG_INFO() << "initLogger() error logDir=" << logDir;
    }
}
#else

// 解析过滤数据包（回调函数）
void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data)
{
    // std::cout << pkt_data << std::endl;
    PrintTCPHeader(pkt_data);
}

void test()
{
    char strFilter[300];
    sprintf(strFilter, "dst host 10.4.16.113 and tcp");
    if(pcap_compile(m_adhandle, &fcode, strFilter, 1, netmask) < 0)
    {
        std::cout << "失败" << std::endl;
    }
    if(pcap_setfilter(m_adhandle, &fcode) < 0)
    {
        std::cout << "失败" << std::endl;
    }

    int res;
    const u_char* pPacketData;
    // 开始捕捉数据包
    pcap_pkthdr *Packet_Header;    // 数据包头
    const u_char * Packet_Data;    // 数据本身
    // pcap_loop(m_adhandle, 0, packet_handler, NULL);
    while((res = pcap_next_ex(m_adhandle, &Packet_Header, &Packet_Data)))
    {
        if(res == 0)
        {
            cout << "超时,被服务器过滤" << endl;
        }
        else
        {
            if(res == 1)
            {
                PrintTCPHeader(Packet_Data);
            }
        }
    }
}

int main(int argc, char *argv[])
{
    // 打开网卡
    OpenAdapter("10.4.16.113");

    char IpAddress[255] = {"www.baidu.com"};
    // std::cin >> IpAddress;

    u_long ulDestIP = inet_addr(IpAddress);
    if(ulDestIP)
    {
        hostent* pHostent = gethostbyname(IpAddress);
        if(pHostent)
        {
            ulDestIP = (*(in_addr*)pHostent->h_addr).s_addr;
        }
        else
        {
            assert(false);
        }
    }

    // 填充地址并生成数据包包头
    char SourceMAC[MAX_PATH] = "88-AE-DD-92-E8-17";
    char SourceIP[MAX_PATH] = "10.4.16.113";
    char SourcePort[MAX_PATH] = "8680";

    char DestinationMAC[MAX_PATH] = "58:69:6c:31:c0:19";
    char DestinationIP[MAX_PATH] = "120.232.145.185";
    // char DestinationMAC[MAX_PATH] = "14-5A-FC-26-ED-FD";
    // char DestinationIP[MAX_PATH] = "172.30.247.167";
    char DestinationPort[MAX_PATH] = "80";

    char DataString[MAX_PATH] = "hello lyshark";
    // CreatePacket(MACStringToBytes(SourceMAC), MACStringToBytes(DestinationMAC), inet_addr(SourceIP), ulDestIP,
                    // atoi(SourcePort), atoi(DestinationPort), (UCHAR*)DataString, (strlen(DataString) + 1));

    CreateTCPPacket(MACStringToBytes(SourceMAC), MACStringToBytes(DestinationMAC), inet_addr(SourceIP), ulDestIP,
                    atoi(SourcePort), atoi(DestinationPort), 2);

    ThreadPool::instance().commit([=](){
        test();
    });

    // 循环发包
    // for (int x = 0; x < 10; x++)
    {
        int a = pcap_sendpacket(m_adhandle, FinalPacket, (/*UserDataLen + */54));
        if (0 != a)
        {
            char* szErr = pcap_geterr(m_adhandle);
            std::cout << a << szErr << std::endl;
            // return 0;
        }
    }

    system("pause");
    return 0;
}

#endif
